MODULE module_wrf_micaps_util
      USE module_wrf_global_attr
      USE module_wrf_getvar
      USE module_namelist_var
      
      CONTAINS 

! data flow buffer: r_buf(:,:,1) 
      SUBROUTINE output_wrf2micaps_3dvar(varinfo,times, &
                                         nx_in,ny_in,nz_in,method)
      INTERFACE 
        SUBROUTINE xy2ll_var3d(in_x,in_y,in_z,xlon,xlat,ivar, &
                         out_x,out_y,ovar,method,debug,miss_val, &
                         s_lon,e_lon,s_lat,e_lat)
        integer      :: in_x,in_y,in_z
        real         :: xlon(in_x,in_y),xlat(in_x,in_y)
        real         :: ivar(in_x,in_y,in_z)
        integer      :: out_x,out_y
        real         :: ovar(out_x,out_y,in_z)
        integer      :: method
        integer      :: debug
        real         :: miss_val
        real,optional:: s_lon,e_lon,s_lat,e_lat

        END SUBROUTINE 
      END INTERFACE 

!      implicit none 
      
! the following parms included in mudule_wrf_var_nameinfo: 
!     interp_v, interp_h, grid_x, grid_y

      TYPE(Tvarinfo), intent(in)   :: varinfo
      character*(*) , intent(in)   :: times
      integer       , intent(in)   :: nx_in, ny_in, nz_in
      integer       , intent(in)   :: method  

      real,dimension(grid_x,grid_y):: lat_out,lon_out
      real,dimension(nx,ny)        :: xlat,xlon
      integer                      :: nx_out,ny_out,nz_out
      real                         :: var_out(grid_x,grid_y,nz_in)
      real                         :: tmp(nx_in,ny_in,nz_in)
      character(len=80)            :: time 
      integer                      :: len_var
      integer                      :: i, j, k 
      real                         :: minval, maxval, interval, bold 
      character(len=30)            :: chs_name
      integer                      :: iunit 
      character(len=80)            :: filename 
      character(len=80)            :: var_to_get
      logical                      :: already_opened
      real                         :: plevel 
 
      ierr = 0     
      time = times

      if (interp_h .EQ. 1) then 
         
        ! convert the value from eq-distance to eq-Lat/lon
        if (debug .GE. 100) write(6,*) " Convert eq-distance to lat/lon grids ..."

        Do k=1,nz_in 
          DO j=1,ny_in 
            DO i=1,nx_in 
              tmp(i,j,k)=r_buf(i,j,k)
            END DO  
          END DO  
        END DO  

        call copy_wrfvar("xlat",nx_out,ny_out,nz_out)
        xlat=r_buf(1:nx,1:ny,1)
        call copy_wrfvar("xlon",nx_out,ny_out,nz_out)
        xlon=r_buf(1:nx,1:ny,1)

        deallocate(r_buf) ; allocate(r_buf(1:nx_in,1:ny_in,1:nz_in))
        Do k=1,nz_in 
          DO j=1,ny_in 
            DO i=1,nx_in 
              r_buf(i,j,k)=tmp(i,j,k)
            END DO  
          END DO  
        END DO  

        if( (nx_in .GT. nx) .or. (ny_in .GT. ny) )then
          call xy_unstagger(nx_in,ny_in,nz_in)
          if (lonlat_user .EQ. 0) then 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                                 grid_x,grid_y,var_out,method,debug,miss_val)
          else 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                                 grid_x,grid_y,var_out,method,debug,miss_val, &
                                 min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        elseif( (nx_in .EQ. nx) .and. (ny_in .EQ. ny) )then
          if (lonlat_user .EQ. 0) then 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                                 grid_x,grid_y,var_out,method,debug,miss_val)
          else 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                                 grid_x,grid_y,var_out,method,debug,miss_val, &
                                 min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        else
          ierr = 1
          if (debug .GT. 0) then
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" wrf_2d_output: cannot match the grids lat/lon"
            write(6,'(60("*"))')
          end if
          return
        end if
      elseif(interp_h .eq. 2) then
        if (grid_x.EQ.nx .AND. grid_y.EQ.ny) then
          if ((nx_in .GT. nx) .OR. (ny_in .GT.ny)) then
            call xy_unstagger(nx_in,ny_in,nz_in)
            var_out = r_buf
          elseif(nx_in.EQ.nx .AND. ny_in.EQ.ny) then
            var_out = r_buf
          else
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" wrf_2d_output: input variable dimension is ",&
                      "smaller than the model domain dimension."
            write(6,'(60("*"))')
          end if
        else
          write(6,'(25("*"),"ERROR",30("*"))')
          write(6,*) " wrf_2d_output: output grid dimension is smaller", &
                      " than the variable actual dimension."
          write(6,'(60("*"))')
        endif
      elseif(interp_h .eq. 3) then  ! output as profile data 
        lon_out = 110
        lat_out = 37
        ! convert the value from eq-distance to eq-Lat/lon
        if (debug .GE. 100) write(6,*) " Convert eq-distance to lat/lon grids ..."

        tmp=r_buf(1:nx_in,1:ny_in,1:nz_in)

        call copy_wrfvar("xlat",nx_out,ny_out,nz_out)
        xlat=r_buf(1:nx,1:ny,1)
        call copy_wrfvar("xlon",nx_out,ny_out,nz_out)
        xlon=r_buf(1:nx,1:ny,1)

        deallocate(r_buf) ; allocate(r_buf(1:nx_in,1:ny_in,1:nz_in))
        r_buf(1:nx_in,1:ny_in,1:nz_in)=tmp

        if( (nx_in .GT. nx) .or. (ny_in .GT. ny) )then
          call xy_unstagger(nx_in,ny_in,nz_in)
          if (lonlat_user .EQ. 0) then 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                              grid_x,grid_y,var_out,method,debug,miss_val)
          else 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                              grid_x,grid_y,var_out,method,debug,miss_val, &
                              min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        elseif( (nx_in .EQ. nx) .and. (ny_in .EQ. ny) )then
          if (lonlat_user .EQ. 0) then 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                              grid_x,grid_y,var_out,method,debug,miss_val)
          else 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,r_buf, &
                              grid_x,grid_y,var_out,method,debug,miss_val, &
                              min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        else
          ierr = 1
          if (debug .GT. 0) then
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" wrf_2d_output: cannot match the grids lat/lon"
            write(6,'(60("*"))')
          end if
          return
        end if
      else 
        if ((nx_in .LE. grid_x) .AND. (ny_in .LE. grid_y)) then 
          var_out=miss_val
          do j = 1, ny_in
            do i = 1, nx_in 
              var_out(i,j,:) = r_buf(i,j,:)
            end do 
          end do 
        else 
          ierr = 1
          if (debug .GT. 0) then 
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*) " wrf_2d_output: output grid dimension is smaller", &
                       " than the variable actual dimension."
            write(6,'(60("*"))')
          end if 
          return
        end if 
      end if 

      var_to_get = varinfo%name
      chs_name   = varinfo%chsname

      if ((grid_x .EQ. 1 ) .AND. (grid_y .EQ.1 )) then 
  
          ! construct a output file name 
          bold = varinfo%bolds(k)
          interval = varinfo%intervals(k)
          call construct_filename2(filename,data_root,var_to_get, &
                                  time, debug, ierr)
  
          ! Search the usable device number for opening input file.
          DO iunit = 10,99
            inquire(iunit,OPENED=already_opened)
            if (.not.already_opened) then
              exit
            endif
          END DO
  
          open(iunit, file=filename, status='unknown', iostat=ierr)
          if (ierr .ne. 0) then 
            if(debug .GT. 0) then 
              write(6,'(60("*"))')
              write(6,*)" ERROR(",ierr,"): couldnot create file ",& 
                                trim(filename)
              write(6,'(60("*"))')
            end if 
          end if 
          call create_micaps_prof(iunit,var_to_get,time, var_out,lon_out,lat_out, & 
                                  chs_name,'海南精细模式')
          if (ierr .ne. 0) then 
            if(debug .GT. 0) then 
              write(6,'(60("*"))')
              write(6,*)" ERROR(",ierr,"):errors occur in creating micaps file."
              write(6,'(60("*"))')
            end if 
          end if 
          close(iunit)
      else 
        do k = 1, nz_in
          plevel = surf_values(k) 
          ! change the unit of height from kilometer to meter. 
          if ((interp_v .EQ. 2).and.(plevel .LT. 100.)) then 
            plevel = plevel * 1000.
          end if 
  
          ! construct a output file name 
          bold = varinfo%bolds(k)
          interval = varinfo%intervals(k)
          call construct_filename(filename,data_root,var_to_get, &
                                  time, plevel, debug, ierr)
  
          ! Search the usable device number for opening input file.
          DO iunit = 10,99
            inquire(iunit,OPENED=already_opened)
            if (.not.already_opened) then
              exit
            endif
          END DO
           
          open(iunit, file=filename, status='unknown', iostat=ierr)
          if (ierr .ne. 0) then 
            if(debug .GT. 0) then 
              write(6,'(60("*"))')
              write(6,*)" ERROR(",ierr,"): couldnot create file ",& 
                                trim(filename)
              write(6,'(60("*"))')
            end if 
          end if 
          call create_micaps_4(iunit,var_to_get,time,plevel,   &
                               var_out(:,:,k),interval,bold,chs_name,'海南精细模式')
          if (ierr .ne. 0) then 
            if(debug .GT. 0) then 
              write(6,'(60("*"))')
              write(6,*)" ERROR(",ierr,"):errors occur in creating micaps file."
              write(6,'(60("*"))')
            end if 
          end if 
          close(iunit)
  
        END DO 
      endif  ! if (grid_x .EQ. 0 ) .AND. (grid_y .EQ.0 ) then 
      return 
      END SUBROUTINE output_wrf2micaps_3dvar

! data flow buffer: r_buf(:,:,1) 
      SUBROUTINE output_wrf2micaps_2dvar(varinfo,times,lvl, &
                                         nx_in,ny_in, method)
      INTERFACE 
        SUBROUTINE xy2ll(in_x,in_y,xlon,xlat,ivar, &
                         out_x,out_y,ovar,method,debug,miss_val, &
                         s_lon,e_lon,s_lat,e_lat)
        integer      :: in_x,in_y
        real         :: xlon(in_x,in_y),xlat(in_x,in_y)
        real         :: ivar(in_x,in_y)
        integer      :: out_x,out_y
        real         :: ovar(out_x,out_y)
        integer      :: method
        integer      :: debug
        real         :: miss_val
        real,optional:: s_lon,e_lon,s_lat,e_lat

        END SUBROUTINE 
      END INTERFACE 

!      implicit none 
      
! the following parms included in mudule_wrf_var_nameinfo: 
!     data_root, interp_v, interp_h, grid_x, grid_y

      TYPE(Tvarinfo), intent(in)   :: varinfo
      character*(*) , intent(in)   :: times
      real          , intent(in)   :: lvl
      integer       , intent(in)   :: nx_in, ny_in
      integer       , intent(in)   :: method  

      real,dimension(grid_x,grid_y):: lat_out,lon_out,var_out
      real,dimension(nx_in,ny_in)  :: tmp
      real,dimension(nx,ny)        :: xlat,xlon
      integer                      :: nx_out,ny_out,nz_out
      character(len=80)            :: time 
      integer                      :: len_var
      integer                      :: i, j, k 
      real                         :: minval, maxval, interval, bold 
      character(len=30)            :: chs_name
      integer                      :: iunit 
      character(len=80)            :: filename 
      character(len=80)            :: var_to_get
      logical                      :: already_opened
      real                         :: plevel 
 
      ierr = 0     
      time = times
      plevel = lvl 

      if (interp_h .EQ. 1) then 
         
        ! convert the value from eq-distance to eq-Lat/lon
        if (debug .GE. 100) write(6,*) " Convert eq-distance to lat/lon grids ..."

        tmp=r_buf(1:nx_in,1:ny_in,1)

        call copy_wrfvar("xlat",nx_out,ny_out,nz_out)
        xlat=r_buf(1:nx,1:ny,1)
        call copy_wrfvar("xlon",nx_out,ny_out,nz_out)
        xlon=r_buf(1:nx,1:ny,1)

        r_buf(1:nx_in,1:ny_in,1)=tmp

        if( (nx_in .GT. nx) .or. (ny_in .GT. ny) )then
          call xy_unstagger(nx_in,ny_in,1)
          if (lonlat_user .EQ. 0) then 
            call xy2ll( nx,ny,xlon,xlat,r_buf, &
                        grid_x,grid_y,var_out,method,debug,miss_val)
          else 
            call xy2ll( nx,ny,xlon,xlat,r_buf, &
                        grid_x,grid_y,var_out,method,debug,miss_val, &
                        min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        elseif( (nx_in .EQ. nx) .and. (ny_in .EQ. ny) )then
          if (lonlat_user .EQ. 0) then 
            call xy2ll( nx,ny,xlon,xlat,r_buf, &
                        grid_x,grid_y,var_out,method,debug,miss_val)
          else 
            call xy2ll( nx,ny,xlon,xlat,r_buf, &
                        grid_x,grid_y,var_out,method,debug,miss_val, &
                        min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        else
          ierr = 1
          if (debug .GT. 0) then
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" wrf_2d_output: cannot match the grids lat/lon"
            write(6,'(60("*"))')
          end if
          return
        end if
      elseif(interp_h .eq. 2) then
        if (grid_x.EQ.nx .AND. grid_y.EQ.ny) then
          if ((nx_in .GT. nx) .OR. (ny_in .GT.ny)) then
            call xy_unstagger(nx_in,ny_in,1)
            var_out = r_buf(:,:,1)
          elseif(nx_in.EQ.nx .AND. ny_in.EQ.ny) then
            var_out = r_buf(:,:,1)
          else
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" wrf_2d_output: input variable dimension is ",&
                      "smaller than the model domain dimension."
            write(6,'(60("*"))')
          end if
        else
          write(6,'(25("*"),"ERROR",30("*"))')
          write(6,*) " wrf_2d_output: output grid dimension is smaller", &
                      " than the variable actual dimension."
          write(6,'(60("*"))')
        endif
      else 
        if ((nx_in .LE. grid_x) .AND. (ny_in .LE. grid_y)) then 
          var_out=miss_val
          do j = 1, ny_in
            do i = 1, nx_in 
              var_out(i,j) = r_buf(i,j,1)
            end do 
          end do 
        else 
          ierr = 1
          if (debug .GT. 0) then 
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*) " wrf_2d_output: output grid dimension is smaller", &
                       " than the variable actual dimension."
            write(6,'(60("*"))')
          end if 
          return
        end if 
      end if 

      ! change the unit of height from kilometer to meter. 
      if ((interp_v .EQ. 2).and.(plevel .LT. 100.)) then 
        plevel = plevel * 1000.
      end if 

      ! construct a output file name 
      var_to_get = varinfo%name
      chs_name   = varinfo%chsname
      bold = varinfo%bolds(1)
      interval = varinfo%intervals(1)
      call construct_filename(filename,data_root,var_to_get, &
                                    time, plevel, debug, ierr)

      ! Search the usable device number for opening input file.
      DO iunit = 10,99
        inquire(iunit,OPENED=already_opened)
        if (.not.already_opened) then
          exit
        endif
      END DO

      open(iunit, file=filename, status='unknown', iostat=ierr)
      if (ierr .ne. 0) then 
        if(debug .GT. 0) then 
          write(6,'(60("*"))')
          write(6,*)" ERROR(",ierr,"): couldnot create file ",& 
                            trim(filename)
          write(6,'(60("*"))')
        end if 
      end if 
      
      call create_micaps_4(iunit,var_to_get,time,plevel,   &
                           var_out,interval,bold,chs_name, '海南精细模式')
      
      if (ierr .ne. 0) then 
        if(debug .GT. 0) then 
          write(6,'(60("*"))')
          write(6,*)" ERROR(",ierr,"):errors occur in creating micaps file."
          write(6,'(60("*"))')
        end if 
      end if 
      close(iunit)

      END SUBROUTINE output_wrf2micaps_2dvar

      SUBROUTINE output_wrf2micaps_wind(varinfo,times,u,v,nx_in,ny_in,nz_in, &
                                        method)
      INTERFACE 
        SUBROUTINE xy2ll_var3d(in_x,in_y,in_z,xlon,xlat,ivar, &
                         out_x,out_y,ovar,method,debug,miss_val, &
                         s_lon,e_lon,s_lat,e_lat)
        integer      :: in_x,in_y,in_z
        real         :: xlon(in_x,in_y),xlat(in_x,in_y)
        real         :: ivar(in_x,in_y,in_z)
        integer      :: out_x,out_y
        real         :: ovar(out_x,out_y,in_z)
        integer      :: method
        integer      :: debug
        real         :: miss_val
        real,optional:: s_lon,e_lon,s_lat,e_lat

        END SUBROUTINE 
      END INTERFACE 

!      implicit none 
      
      TYPE(Tvarinfo), intent(in)   :: varinfo
      character*(*) , intent(in)   :: times
      integer       , intent(in)   :: nx_in, ny_in, nz_in
      real          , intent(in)   :: u(nx_in,ny_in,nz_in),v(nx_in,ny_in,nz_in) 
      integer       , intent(in)   :: method  

      real,dimension(grid_x,grid_y,nz_in):: u_out,v_out
      real,dimension(grid_x,grid_y):: lat_out,lon_out
      real,dimension(nx,ny)        :: xlat,xlon
      integer                      :: nx_out,ny_out,nz_out
      character(len=80)            :: time 
      integer                      :: len_var
      integer                      :: i, j, k
      integer                      :: ierr
      integer                      :: iunit 
      character(len=80)            :: filename 
      character(len=80)            :: var_to_get
      logical                      :: already_opened
      real                         :: plevel 
 
      
      ierr = 0     
      time = times

!     relate the u and v value to the grids' Latitude/Longitude. 
      if (interp_h .EQ. 1) then 
        ! convert the value from eq-distance to eq-Lat/lon
        if (debug .GE. 100) write(6,*) " Convert eq-distance to lat/lon grids ..."

        call copy_wrfvar("xlat",nx_out,ny_out,nz_out)
        xlat=r_buf(1:nx,1:ny,1)
        call copy_wrfvar("xlon",nx_out,ny_out,nz_out)
        xlon=r_buf(1:nx,1:ny,1)

        if( (nx_in .EQ. nx) .and. (ny_in .EQ. ny) )then
          if (lonlat_user .EQ. 0) then 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,u, &
                            grid_x,grid_y,u_out,method,debug,miss_val)
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,v, &
                            grid_x,grid_y,v_out,method,debug,miss_val)
          else 
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,u, &
                            grid_x,grid_y,u_out,method,debug,miss_val, &
                            min_lon_user,max_lon_user,min_lat_user,max_lat_user)
            call xy2ll_var3d( nx,ny,nz_in,xlon,xlat,v, &
                            grid_x,grid_y,v_out,method,debug,miss_val, &
                            min_lon_user,max_lon_user,min_lat_user,max_lat_user)
          endif 
        else
          ierr = 1
          if (debug .GT. 0) then
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" output_wrf2micaps_wind: ",&
                      "cannot match the grids lat/lon"
            write(6,'(60("*"))')
          end if
          return
        end if
      elseif(interp_h .eq. 2) then
        if (grid_x.EQ.nx .AND. grid_y.EQ.ny) then
          if(nx_in.EQ.nx .AND. ny_in.EQ.ny) then
            u_out = u
            v_out = v
          else
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" output_wrf2micaps_wind: input variable dimension",&
                      " is smaller than the model domain dimension."
            write(6,'(60("*"))')
          end if
        else
          write(6,'(25("*"),"ERROR",30("*"))')
          write(6,*) " output_wrf2micaps_wind: output grid dimension", &
                      " is smaller than the variable actual dimension."
          write(6,'(60("*"))')
        endif
      else 
        if ((nx_in .LE. grid_x) .AND. (ny_in .LE. grid_y)) then 
          if(nx_in.EQ.nx .AND. ny_in.EQ.ny) then
            u_out   = miss_val
            v_out   = miss_val
            u_out(1:nx_in,1:ny_in,:) = u(1:nx_in,1:ny_in,:)
            v_out(1:nx_in,1:ny_in,:) = v(1:nx_in,1:ny_in,:)
          else
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*)" output_wrf2micaps_wind: input variable dimension",&
                      " is mismatch the model domain dimension."
            write(6,'(60("*"))')
          end if 
        else 
          ierr = 1
          if (debug .GT. 0) then 
            write(6,'(25("*"),"ERROR",30("*"))')
            write(6,*) " output_wrf2micaps_wind: output grid dimension is ",&
                       "smaller than the variable actual dimension."
            write(6,'(60("*"))')
          end if 
          return
        end if 
      end if 

      var_to_get = varinfo%name
      len_var = len_trim(var_to_get)

      DO k = 1, nz_in
        if ( var_to_get(1:len_var).EQ."wind10") then 
          plevel = 2001
        else 
          plevel = surf_values(k)
        endif 

!    change the unit of height from kilometer to meter. 
        if ((interp_v .EQ. 2).and.(plevel .LT. 100.)) then 
          plevel = plevel * 1000.
        end if 

        ! Search the usable device number for opening input file.
        DO iunit = 10,99
          inquire(iunit,OPENED=already_opened)
          if (.not.already_opened) then
            exit
          endif
        END DO

        call construct_filename(filename,data_root,var_to_get(1:len_var), &
                                time, plevel, debug, ierr)
  
        open(iunit, file=filename, status='unknown', iostat=ierr)

        call create_micaps_11(iunit,var_to_get,time,plevel, &
                              u_out(:,:,k),v_out(:,:,k))
        if (ierr .ne. 0) then 
          if (debug .GT. 0) write(6,*) " errors occur in creating micaps file."
        end if 
        close(iunit)

      END DO ! k 

      return 

      END SUBROUTINE output_wrf2micaps_wind

!!!
!!!  length of time must be greater than or equal to 24. 
!!!

      SUBROUTINE construct_filename(filename, directory, varname, &
                                    time, plevel, debug, ierr)  
!      implicit none 

      character(len=*), intent(out)  :: filename 
      character(len=*), intent(in)   :: directory
      character(len=*), intent(in)   :: varname
      character(len=*), intent(in)   :: time
      real,             intent(in)   :: plevel 
      integer,          intent(in)   :: debug 
      integer,          intent(out)  :: ierr 
       
      character(len=80)              :: str_buf 
      real                           :: plevel_new
      integer                        :: plevel_int,len_var
      character(len=1)               :: slash

      slash = "/"
      ierr = 0 
     
      len_var = len_trim(varname)
      str_buf = varname(1:len_var) 
      
      if (plevel .LT. 0.) then 
        ierr = 1 
        if (debug .GT. 0) write(6,*) " the pressure is negative :",plevel 
        return 
      end if 

      plevel_new = plevel

      ! 确保层次数为大于1的4位整数 
      do while (plevel_new .LT. 1.0) 
        plevel_new = plevel_new * 10.
      end do     ! do while (plevel_new .LT. 1.0)

      ! 确保层次数为小于10000的4位整数 
      do while (plevel_new .GT. 10000.) 
        plevel_new = plevel_new / 10.
      end do     ! do while (plevel_new .GT. 10000.)

      plevel_int = INT(plevel_new) 

      write(str_buf,'(i4.4)')  plevel_int

      len_var = len_trim(directory)
      if (directory(len_var:len_var) .EQ. slash) then 
        filename = directory(1:len_trim(directory)) // & 
                   varname(1:len_trim(varname))     // &
                   "_"//str_buf(1:4)//"_"           // &
                   time(1:4)//time(6:7)//time(9:10) // &
                   time(12:13)//"."// time(22:24) 
      else  
        filename = directory(1:len_trim(directory)) // & 
                   slash//varname(1:len_trim(varname))// &
                   "_"//str_buf(1:4)//"_"           // &
                   time(1:4)//time(6:7)//time(9:10) // &
                   time(12:13)//"."// time(22:24) 
      end if 
      if (debug .GE. 100) write(6,*) " filename :", filename(1:len_trim(filename))
      return 
 
      END SUBROUTINE construct_filename 
!!!
!!!  length of time must be greater than or equal to 24. 
!!!

      SUBROUTINE construct_filename2(filename, directory, varname, &
                                    time, debug, ierr)  
!      implicit none 

      character(len=*), intent(out)  :: filename 
      character(len=*), intent(in)   :: directory
      character(len=*), intent(in)   :: varname
      character(len=*), intent(in)   :: time
      integer,          intent(in)   :: debug 
      integer,          intent(out)  :: ierr 
       
      character(len=80)              :: str_buf 
      character(len=1)               :: slash
      integer                        :: len_var

      slash = "/"
      ierr = 0 
     
      len_var = len_trim(varname)
      
      len_var = len_trim(directory)
      if (directory(len_var:len_var) .EQ. slash) then 
        filename = directory(1:len_trim(directory)) // & 
                   varname(1:len_trim(varname))//"_"// &
                   time(1:4)//time(6:7)//time(9:10) // &
                   time(12:13)//"."// time(22:24) 
      else  
        filename = directory(1:len_trim(directory)) // & 
                   slash//varname(1:len_trim(varname))// &
                   "_"//time(1:4)//time(6:7)//time(9:10) // &
                   time(12:13)//"."// time(22:24) 
      end if 
      if (debug .GE. 100) write(6,*) " filename :", filename(1:len_trim(filename))
      return 
 
      END SUBROUTINE construct_filename2 

      SUBROUTINE create_micaps_2(iunit,varname,time,plevel,u,v,&
                                 xlon,xlat,altitude,order,height,tc,td) 
     
!      implicit none

      integer,          intent(in) :: iunit 
      character(len=*), intent(in) :: varname
      character(len=*), intent(in) :: time
      real,             intent(in) :: plevel
      real,             intent(in) :: u(grid_x,grid_y),v(grid_x,grid_y),&
                                      altitude(grid_x,grid_y),&
                                      height(grid_x,grid_y),&
                                      tc(grid_x,grid_y),td(grid_x,grid_y),&
                                      xlon(grid_x,grid_y),xlat(grid_x,grid_y)

      integer,           intent(in):: order(grid_x,grid_y)

      character(len=80)      :: diamond_line
      character(len=300)     :: head_line
      real                   :: plevel_new
      integer                :: plevel_int
      integer                :: micaps_data_type
      integer                :: len_var,len_p
      character(len=80)      :: plevel_str
      character(len=80)      :: var_chs_name
      integer                :: i,j,grid_id
      real                   :: var_real
      real                   :: alpha
 
      ierr = 0
      
! get the pressure level string. 
      SELECT CASE (interp_v)
      CASE (0) 
        plevel_new = plevel
        do while (plevel_new .LT. 1.0)
          plevel_new = plevel_new * 10.
        end do     ! do while (plevel_new .LT. 1.0)
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        plevel_int = INT(plevel_new)
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        else 
          plevel_int = INT(plevel)
          write(plevel_str,'(a,i4.4,a)')  '_',plevel_int,'_'
        end if
      CASE (1)
      if (plevel .LT. 0.) then
        ierr = 2
        if (debug .GT. 0) write(6,*) ' error:the pressure is negative= ',plevel
        return
      end if
      plevel_new = plevel
      do while (plevel_new .LT. 1.0)
        plevel_new = plevel_new * 10.
      end do     ! do while (plevel_new .LT. 1.0)
      do while (plevel_new .GT. 10000.)
        plevel_new = plevel_new / 10.
      end do     ! do while (plevel_new .GT. 10000.)
      plevel_int = INT(plevel_new) 
      if (plevel_int .EQ.2001) then
        plevel_str = '地面'
      elseif (plevel_int .EQ.2013) then 
        plevel_str = '海平面'
      else 
        ! 在micaps数据中，直接输出以百帕为单位。
        plevel_int = INT(plevel)
        write(plevel_str,'(i4.4,a)')  plevel_int,"百帕"
      end if 
      CASE (2) 
        plevel_new = plevel
        do while (plevel_new .LT. 1.0)
          plevel_new = plevel_new * 10.
        end do     ! do while (plevel_new .LT. 1.0)
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        plevel_int = INT(plevel_new) 
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        else
          ! 在micaps数据中，直接输出以米为单位。
          plevel_int = INT(plevel) 
          write(plevel_str,'(i6,a)') plevel_int, '米'
          call l_trim(plevel_str)
        end if
      CASE DEFAULT 
      END SELECT 

      SELECT CASE (varname)
      CASE ('wind') 
        micaps_data_type = 2 
        var_chs_name = '风场' 
      CASE DEFAULT 
        micaps_data_type = 2 
        var_chs_name = '_'//varname
      END SELECT 
      
      len_var = len_trim(var_chs_name)
      len_p = len_trim(plevel_str)
      diamond_line = 'diamond 2 '//time(1:4)//time(6:7)//&
                      time(9:13)//'时次'      //         &
                      time(22:24)// '时效海南精细模式' //         &
                      plevel_str(1:len_p)      //         &
                      var_chs_name(1:len_var)
      write(head_line,1200) time(3:4),time(6:7),time(9:10),  &
                             time(12:13),plevel_int,grid_x*grid_y 
 1200 format(6x,4(a2,1x),i6,1x,i8,1x) 
        len_var = len_trim(diamond_line)
        write(iunit,*) diamond_line(1:len_var)
        len_var = len_trim(head_line)
        write(iunit,*) head_line(1:len_var)

        grid_id = 0
        do j = 1, grid_y
        do i = 1, grid_x
        eps = abs(miss_val*epsilon)
        if ( (abs(u(i,j)-miss_val).GT.eps).OR.     &
             (abs(v(i,j)-miss_val).GT.eps)    ) then 
          grid_id = grid_id + 1 
          if (u(i,j) .GT. 1e-7) then 
            alpha = 270. - ATAN(v(i,j)/u(i,j))/radians_per_degree
          elseif (u(i,j) .LT. -1e-7)  then 
            alpha = 90. - ATAN(v(i,j)/u(i,j))/radians_per_degree 
          else 
            alpha = 90. + SIGN(90.,v(i,j))
          end if
          if (alpha .GT. 360.) then 
            alpha = alpha - 360.
          elseif (alpha .LT. 0.) then 
            alpha = alpha +360. 
          end if  
          var_real = sqrt(u(i,j)*u(i,j)+v(i,j)*v(i,j))
          write(iunit, 1201) grid_id,xlon(i,j), xlat(i,j), &
                             altitude(i,j),order(i,j),     &
                             height(i,j),tc(i,j),td(i,j),  &
                             alpha, var_real
        end if 
        end do    ! do i= 1, grid_x
      end do    ! do j= 1, grid_y
 1201 format(1x,i8,1x,3(f10.4,1x),i4,1x,5(f7.1,1x))

      return 

      END SUBROUTINE create_micaps_2 

      SUBROUTINE create_micaps_4(iunit,varname,time,plevel,var, &
                                 interval_in,bold_in,chsname_in,model_name) 
!      implicit none
! the following parameters are included in module_namelist_var: 
!     grid_x,grid_y
! the following parameters are included in module_wrf_getvar: 
!     min_lat,max_lat,range_lat,min_lon,max_lon,range_lon
! the following parameters are included in module_wrf_global_attr: 
!     debug,miss_val,ierr

      integer,              intent(in)   :: iunit 
      character(len=*),     intent(in)   :: varname
      character(len=*),     intent(in)   :: time
      real,                 intent(in)   :: plevel
      real,dimension(grid_x,grid_y),intent(in)   :: var
      real,                 intent(in)   :: interval_in,bold_in
      character(len=*),     intent(in)   :: chsname_in
      character(len=*),     intent(in)   :: model_name

      real                           :: s_lon,e_lon,s_lat,e_lat 
      real                           :: minval, maxval
      character(len=80)              :: str_buf
      character(len=80)              :: diamond_line
      character(len=300)             :: head_line
      real                           :: lat_delta, lon_delta
      real                           :: interval, bold
      real                           :: min_out, max_out
      real                           :: plevel_new
      integer                        :: plevel_int
      integer                        :: smooth
      integer                        :: len_var,len_p,len_m
      character(len=80)              :: plevel_str
      character(len=80)              :: chs_name
      integer                        :: i,j,grid_id
      integer                        :: var_int
      real                           :: var_real
 
      ierr = 0
      
! set the smooth coefficient value 

      smooth = 2
! check the maxval and minval 

!yry 将高度场写成为势十米
!      if (plevel .GT. 100 .and. plevel .LT. 925 .and. varname(1:1) .EQ. 'Z')  then
!       var=var/10.
!      end if
!yry 
!     Get the maximum, minimum and middle valule of the variable.
      minval = 1e20
      maxval = -1e20
      eps = ABS(miss_val*epsilon)
      do j=1,grid_y
        do i=1,grid_x
          if ( ABS(var(i,j)-miss_val) .GT. eps ) then 
            if(minval>var(i,j))then
               minval=var(i,j)
            end if 
            if(maxval<var(i,j))then
              maxval=var(i,j)
            end if
          end if 
        end do
      end do
      eps = abs(minval*epsilon)
      if ( (maxval - minval) .LT. -eps ) then 
        ierr = 1
        if (debug .GT. 0) then 
          write(6,'(60("*"))') 
          write(6,*)" ERROR(",ierr,"): max/min value is wrong. max/min:", &
                             maxval,minval 
          write(6,'(60("*"))')
        end if 
        return
      else 
        if (debug .GE. 100) write(6,*) 'Min/max values:', minval, maxval
      end if 

! get the pressure level string. 
      SELECT CASE (interp_v)
      CASE (0) 
        plevel_new = plevel
        do while (plevel_new .LT. 1.0)
          plevel_new = plevel_new * 10.
        end do     ! do while (plevel_new .LT. 1.0)
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        plevel_int = INT(plevel_new) 
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        else 
          plevel_int = INT(plevel)
          write(plevel_str,'(i4)')  plevel_int
          call l_trim(plevel_str)
          plevel_str = '第'//TRIM(plevel_str)//'层'
        end if
      CASE (1)
      if (plevel .LT. 0.) then
        ierr = 2
        if (debug .GT. 0) write(6,*) ' error:the pressure is negative= ',plevel
        return
      end if
      plevel_new = plevel
      do while (plevel_new .LT. 1.0)
        plevel_new = plevel_new * 10.
      end do     ! do while (plevel_new .LT. 1.0)
      do while (plevel_new .GT. 10000.)
        plevel_new = plevel_new / 10.
      end do     ! do while (plevel_new .GT. 10000.)
      plevel_int = INT(plevel_new) 
      if (plevel_int .EQ.2001) then
        plevel_str = '地面'
      elseif (plevel_int .EQ.2013) then 
        plevel_str = '海平面'
      elseif ((varname(1:2) .EQ. 'SM').OR.(varname(1:4).EQ.'TSLB')) then 
        write(plevel_str,'(a,i2,a)') '第', INT(plevel_new), '层'
        call delete_space(plevel_str)
      else 
        ! 在micaps数据中，直接输出以百帕为单位
        plevel_int = INT(plevel)
        write(plevel_str,'(i4)')  plevel_int
        call l_trim(plevel_str)
        plevel_str = TRIM(plevel_str)// '百帕'
      end if 
      CASE (2) 
        plevel_new = plevel
        do while (plevel_new .LT. 1.0)
          plevel_new = plevel_new * 10.
        end do     ! do while (plevel_new .LT. 1.0)
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        plevel_int = INT(plevel_new) 
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        elseif ((varname(1:2) .EQ. 'SM').OR.(varname(1:4).EQ.'TSLB')) then 
          write(plevel_str,'(a,i2,a)') '第', INT(plevel_new), '层'
          call delete_space(plevel_str)
        else
          ! 在micaps数据中，直接输出以米为单位 。 
          plevel_int = INT(plevel) 
          write(plevel_str,'(i6,a)') plevel_int,'米'
          call l_trim(plevel_str)
        end if
      CASE DEFAULT 
      END SELECT 

! get the delta longitude and delta latitude. 
      if ( (grid_x == 0 ) .or.(grid_y == 0) ) then 
        if (debug .GT. 0) write(6,*) " dimensions of output array is wrong." 
        if (debug .GT. 0) write(6,*) " grid_x = ", grid_x, " grid_y = ",grid_y 
        ierr = 3 
        return 
      end if  

      if (lonlat_user .EQ. 0) then 
        s_lon = min_lon ; e_lon = max_lon 
        s_lat = min_lat ; e_lat = max_lat 
      else 
        s_lon = min_lon_user ; e_lon = max_lon_user 
        s_lat = min_lat_user ; e_lat = max_lat_user 
      endif 
      lon_delta = (e_lon - s_lon) / (grid_x -1)
      lat_delta = (e_lat - s_lat) / (grid_y -1)

      ! set the interval, bold, and chs_name 
      if (chsname_in == '') then 
        chs_name = '_'//trim(varname)
      else 
        chs_name = chsname_in
      end if 
      if (interval_in == miss_val) then 
        interval = (maxval-minval)/10. 
        eps = abs(minval/10. * epsilon)
        if (interval .lt. eps) interval = 0.1
      else 
        interval = interval_in 
      end if 
      if (bold_in == miss_val) then 
        bold = 0.
      else 
        bold = bold_in 
      end if 

      len_var = len_trim(chs_name)
      len_m = len_trim(model_name)
      len_p = len_trim(plevel_str)
      diamond_line = 'diamond 4 '//time(1:4)//time(6:7)//  &
                     time(9:13)//'时次'         //         &
                     time(22:24)//'时效'//model_name(1:len_m)//&
                     plevel_str(1:len_p)          //        &
                     chs_name(1:len_var)
      max_out = INT((maxval-bold)/interval+SIGN(0.99,maxval)) &
                   * interval + bold
      min_out = INT((minval-bold)/interval+SIGN(0.99,minval)) &
                   * interval + bold

      write(head_line,400) time(3:4),time(6:7),time(9:10),  &
                           time(12:13), time(22:24),        &
                           plevel_int,lon_delta, lat_delta,  &
                           s_lon,e_lon,s_lat,e_lat,  grid_x,grid_y, &
                           interval,min_out,max_out,smooth,bold
 400 format(6x,4(a2,1x),a3,1x,i6,1x,2(f8.6,1x),4(f6.2,1x),2(i4,1x),3(f8.2,1x), &
            i4, 1x,f8.2) 
      len_var = len_trim(diamond_line)
      write(iunit,*) diamond_line(1:len_var)
      len_var = len_trim(head_line)
      write(iunit,*) head_line(1:len_var)
      do j = 1, grid_y     
         write(iunit, '(10f7.1)') (var(i,j),i=1,grid_x)
      end do    ! do j= 1, grid_y

      return 

      END SUBROUTINE create_micaps_4 

      SUBROUTINE create_micaps_prof(iunit,varname,time,var, olon,olat,chsname_in,model_name) 
!      implicit none
! the following parameters are included in module_namelist_var: 
!     grid_x,grid_y
!     nlevel, surf_values 
! the following parameters are included in module_wrf_getvar: 
!     min_lat,max_lat,range_lat,min_lon,max_lon,range_lon
! the following parameters are included in module_wrf_global_attr: 
!     debug,miss_val,ierr

      integer,              intent(in)   :: iunit 
      character(len=*),     intent(in)   :: varname
      character(len=*),     intent(in)   :: time
      real,                 intent(in)   :: var(grid_x,grid_y,nlevel) 
      real,                 intent(in)   :: olon(grid_x,grid_y),olat(grid_x,grid_y)  
      character(len=*),     intent(in)   :: chsname_in
      character(len=*),     intent(in)   :: model_name

      character(len=80)              :: diamond_line
      character(len=300)             :: head_line
      integer                        :: len_var,len_p,len_m
      character(len=80)              :: plevel_str
      character(len=80)              :: chs_name
      integer                        :: i,j,k
 
      ierr = 0
      
! get the pressure level string. 
      SELECT CASE (interp_v)
      CASE (0) 
        plevel_str = '模式面'
      CASE (1)
        plevel_str = '等压面'
      CASE (2) 
        plevel_str = '等高面'
      CASE DEFAULT 
      END SELECT 

! get the delta longitude and delta latitude. 
      if ( (grid_x == 0 ) .or.(grid_y == 0) ) then 
        if (debug .GT. 0) write(6,*) " dimensions of output array is wrong." 
        if (debug .GT. 0) write(6,*) " grid_x = ", grid_x, " grid_y = ",grid_y 
        ierr = 3 
        return 
      end if  

      ! set the interval, bold, and chs_name 
      if (chsname_in == '') then 
        chs_name = '_'//trim(varname)
      else 
        chs_name = chsname_in
      end if 

      len_var = len_trim(chs_name)
      len_m = len_trim(model_name)
      len_p = len_trim(plevel_str)
      diamond_line = 'diamond 0'// time(1:4)//time(6:7)//  &
                     time(9:13)//'时次'         //         &
                     time(22:24)//'时效'//model_name(1:len_m)//&
                     plevel_str(1:len_p)          //        &
                     chs_name(1:len_var) // '垂直廓线' 

      len_var = len_trim(diamond_line)
      write(iunit,*) diamond_line(1:len_var)

      do j = 1, grid_y
        do i = 1, grid_x
          write(head_line,'(i8.8, 2f8.3)') i*1000+j,olon(grid_x,grid_y),olat(grid_x,grid_y)
          len_var = len_trim(head_line)
          write(iunit,*) head_line(1:len_var)
          do k = 1, nlevel
            write(iunit, '(2f7.1)') surf_values(k), var(i,j,k)
          enddo ! do k = 1, nlevel 
        end do    ! do i= 1, grid_x
      end do    ! do j= 1, grid_y

      return 

      END SUBROUTINE create_micaps_prof


      SUBROUTINE create_micaps_11(iunit,varname,time,plevel,u,v) 
     
!      implicit none

      integer,              intent(in)   :: iunit 
      character(len=*),     intent(in)   :: varname
      character(len=*),     intent(in)   :: time
      real,                 intent(in)   :: plevel
      real,dimension(grid_x,grid_y),intent(in)   :: u,v

      character(len=80)              :: diamond_line
      character(len=300)             :: head_line
      real                           :: s_lon,e_lon,s_lat,e_lat 
      real                           :: plevel_new
      integer                        :: plevel_int
      real                           :: lon_delta,lat_delta
      integer                        :: len_var,len_p
      character(len=80)              :: plevel_str
      character(len=80)              :: var_chs_name
      integer                        :: i,j
 
      ierr = 0
      
! calculate the delta longitude/latitude. 
      if (lonlat_user .EQ. 0) then 
        s_lon = min_lon ; e_lon = max_lon 
        s_lat = min_lat ; e_lat = max_lat 
      else 
        s_lon = min_lon_user ; e_lon = max_lon_user 
        s_lat = min_lat_user ; e_lat = max_lat_user 
      endif 
      lon_delta = (e_lon-s_lon)/ (grid_x - 1)
      lat_delta = (e_lat-s_lat)/ (grid_y - 1)

! get the pressure level string. 
      SELECT CASE (interp_v)
      CASE (0) 
        plevel_new = plevel
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        !plevel_int = plevel_new * 10. 
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        else 
          plevel_int = plevel_new 
          write(plevel_str,'(a,i4.4,a)')  '_',plevel_int,'_'
        end if
      CASE (1)
        if (plevel .LT. 0.) then
          ierr = 2
          if (debug .GT. 0) write(6,*) ' error:the pressure is negative= ',plevel
          return
        end if
        plevel_new = plevel
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        plevel_int = INT(plevel_new) 
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        else 
          plevel_int = INT(plevel) 
          write(plevel_str,'(i4.4,a)')  plevel_int,"百帕"
        end if 
      CASE (2) 
        plevel_new = plevel
        do while (plevel_new .LT. 1.0)
          plevel_new = plevel_new * 10.
        end do     ! do while (plevel_new .LT. 1.0)
        do while (plevel_new .GT. 10000.)
          plevel_new = plevel_new / 10.
        end do     ! do while (plevel_new .GT. 10000.)
        plevel_int = INT(plevel_new) 
        if (plevel_int .EQ.2001) then
          plevel_str = '地面'
        elseif (plevel_int .EQ.2013) then 
          plevel_str = '海平面'
        else
          ! 在micaps数据中，直接输出以米为单位 。 
          plevel_int = INT(plevel) 
          write(plevel_str,'(i5,a)') plevel_int, '米'
          call l_trim(plevel_str)
        end if
      CASE DEFAULT 
      END SELECT 

      SELECT CASE (varname)
      CASE ('stream') 
        var_chs_name = '流线' 
      CASE DEFAULT
        var_chs_name = '_'//varname
      END SELECT 
      
      len_var = len_trim(var_chs_name)
      len_p = len_trim(plevel_str)
      diamond_line = 'diamond 11 '//time(1:4)//time(6:7)//&
                      time(9:13)//'时次'      //         &
                      time(22:24)// '时效海南精细模式' //         &
                      plevel_str(1:len_p)      //         &
                      var_chs_name(1:len_var)
      write(head_line,1200) time(3:4),time(6:7),time(9:10),  &
                            time(12:13),time(22:24),plevel_int, &
                            lon_delta,lat_delta,s_lon,e_lon, &
                            s_lat,e_lat,grid_x,grid_y 
 1200 format(6x,4(a2,1x),a3,1x,i6,1x,6(f12.4,1x),2(i8,1x)) 
        len_var = len_trim(diamond_line)
        write(iunit,*) diamond_line(1:len_var)
        len_var = len_trim(head_line)
        write(iunit,*) head_line(1:len_var)

        do j = 1, grid_y
          write(iunit, '(10f7.1)') (u(i,j),i=1,grid_x)
        end do    ! do j= 1, grid_y
        do j = 1, grid_y
          write(iunit, '(10f7.1)') (v(i,j),i=1,grid_x)
        end do    ! do j= 1, grid_y

      return 

      END SUBROUTINE create_micaps_11 

 END MODULE module_wrf_micaps_util
